package com.woniuxy.hrp.web;

import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.woniuxy.hrp.common.AliPayConfig;
import com.woniuxy.hrp.entity.*;
import com.woniuxy.hrp.security.JwtUtil;
import com.woniuxy.hrp.service.PayRecordService;
import com.woniuxy.hrp.service.PayService;
import com.woniuxy.hrp.service.ReservationService;
import com.woniuxy.hrp.service.WalletService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

// xjlugv6874@sandbox.com
// 9428521.24 - 30 = 9428491.24 + 30 = 9428521.24
@RestController
public class AliPayController {

    private static final String GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";
    private static final String FORMAT = "JSON";
    private static final String CHARSET = "UTF-8";
    //签名方式
    private static final String SIGN_TYPE = "RSA2";

    @Resource
    private AliPayConfig aliPayConfig;
    @Autowired
    PayService payService;
    @Autowired
    private ReservationService reservationService;
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    PayRecordService payRecordService;
    @Autowired
    WalletService walletService;

//    @Resource
//    private OrdersMapper ordersMapper;
    @RequestMapping("/api/alipay/chongzhi")
    public void chongzhi(@RequestBody Wallet wallet, HttpServletResponse httpResponse,@RequestHeader String jwt) throws Exception {
        // 1. 创建Client，通用SDK提供的Client，负责调用支付宝的API
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        String id = jwtUtil.getInfo(jwt, "id").toString();

        // 2. 创建 Request并设置Request参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();  // 发送请求的 Request类
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        JSONObject bizContent = new JSONObject();
        int v = (int)(Math.random() * 9000+1000);

        bizContent.set("out_trade_no", "C"+id+v);  // 我们自己生成的订单编号
        bizContent.set("total_amount", wallet.getBalance()); // 订单的总金额
        bizContent.set("subject", "充值");   // 支付的名称
        bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY");  // 固定配置
        request.setBizContent(bizContent.toString());
        // 执行请求，拿到响应的结果，返回给浏览器
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }
    @GetMapping("/api/alipay/pay") // &subject=xxx&traceNo=xxx&totalAmount=xxx
    public void pay(AliPay aliPay, HttpServletResponse httpResponse) throws Exception {
        // 1. 创建Client，通用SDK提供的Client，负责调用支付宝的API
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);

        // 2. 创建 Request并设置Request参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();  // 发送请求的 Request类
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        JSONObject bizContent = new JSONObject();
//        bizContent.set("account", aliPay.getAccount());  // 我们自己生成的订单编号
//        bizContent.set("name", aliPay.getName()); // 订单的总金额
//        bizContent.set("starttime", aliPay.getStarttime());   // 支付的名称
//        bizContent.set("fee",aliPay.getFee());
        int v = (int)(Math.random() * 9000+1000);
        bizContent.set("out_trade_no",  "Y"+aliPay.getDoctorandtimeid().toString()+v);  // 我们自己生成的订单编号
        bizContent.set("total_amount", aliPay.getFee()); // 订单的总金额
        bizContent.set("subject", aliPay.getName());   // 支付的名称
        bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY");  // 固定配置
        request.setBizContent(bizContent.toString());
        // 执行请求，拿到响应的结果，返回给浏览器
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }
    @RequestMapping("/api/alipay/payDPM") // &subject=xxx&traceNo=xxx&totalAmount=xxx
    public void payDPM(@RequestBody AliPay aliPay, HttpServletResponse httpResponse,@RequestHeader String jwt) throws Exception {
        // 1. 创建Client，通用SDK提供的Client，负责调用支付宝的API
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        int id = (int)jwtUtil.getInfo(jwt, "id");
        // 2. 创建 Request并设置Request参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();  // 发送请求的 Request类
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        JSONObject bizContent = new JSONObject();
        String no = "";
        List<Integer> dpm = aliPay.getDpm();
        BigDecimal totalfee= new BigDecimal(0);
        for (Integer integer : dpm) {
            BigDecimal fee = payService.getDPMbyID(integer).getMedicine().getFee();
            Integer num = payService.getDPMbyID(integer).getNum();
            BigDecimal multiply = fee.multiply(new BigDecimal(num));
            totalfee=totalfee.add(multiply);
            no = no +integer;
        }
        int v = (int)(Math.random() * 9000+1000);
        bizContent.set("out_trade_no","M"+no+v );  // 我们自己生成的订单编号
        bizContent.set("total_amount", totalfee); // 订单的总金额
        bizContent.set("subject", id);   // 支付的名称
        bizContent.set("trade_status","药费");
        bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY");  // 固定配置
        request.setBizContent(bizContent.toString());
        // 执行请求，拿到响应的结果，返回给浏览器
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }
    @RequestMapping("/api/alipay/payDPI") // &subject=xxx&traceNo=xxx&totalAmount=xxx
    public void payDPI(@RequestBody AliPay aliPay, HttpServletResponse httpResponse,@RequestHeader String jwt) throws Exception {
        // 1. 创建Client，通用SDK提供的Client，负责调用支付宝的API
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        int id = (int)jwtUtil.getInfo(jwt, "id");
        // 2. 创建 Request并设置Request参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();  // 发送请求的 Request类
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        JSONObject bizContent = new JSONObject();
        String no = "";
        List<Integer> dpm = aliPay.getDpi();
        BigDecimal totalfee= new BigDecimal(0);
        for (Integer integer : dpm) {
            BigDecimal fee = payService.getDPIById(integer).getMitem().getFee();
            totalfee=totalfee.add(fee);
            no = no +integer;
        }
        int v = (int)(Math.random() * 9000+1000);
        bizContent.set("out_trade_no",  "I"+no+v);  // 我们自己生成的订单编号
        bizContent.set("total_amount", totalfee); // 订单的总金额
        bizContent.set("subject", id);   // 支付的名称
        bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY");  // 固定配置
        request.setBizContent(bizContent.toString());
        // 执行请求，拿到响应的结果，返回给浏览器
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }
    @GetMapping("/api/alipay/payNat") // &subject=xxx&traceNo=xxx&totalAmount=xxx
    public void payNat(AliPay aliPay, HttpServletResponse httpResponse) throws Exception {
        // 1. 创建Client，通用SDK提供的Client，负责调用支付宝的API
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        // 2. 创建 Request并设置Request参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();  // 发送请求的 Request类
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        JSONObject bizContent = new JSONObject();
        int v = (int)(Math.random() * 9000+1000);

        bizContent.set("out_trade_no",  "H"+aliPay.getAccount()+v);  // 我们自己生成的订单编号
        bizContent.set("total_amount", aliPay.getFee()); // 订单的总金额
        bizContent.set("subject", aliPay.getName());   // 支付的名称
        bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY");  // 固定配置
        bizContent.set("buyer_pay_amount",aliPay.getAccount());
        request.setBizContent(bizContent.toString());
        // 执行请求，拿到响应的结果，返回给浏览器
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }

    @PostMapping("/alipay/notify")  // 注意这里必须是POST接口
    public String payNotify(HttpServletRequest request) throws Exception {
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            System.out.println("=========支付宝异步回调========");
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
                // System.out.println(name + " = " + request.getParameter(name));
            }
            String sign = params.get("sign");
            String content = AlipaySignature.getSignCheckContentV1(params);
            boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, aliPayConfig.getAlipayPublicKey(), "UTF-8"); // 验证签名
            // 支付宝验签
            if (checkSignature) {
                if((params.get("out_trade_no").substring(0,1)).equals("H")){
                    String account = params.get("out_trade_no").substring(1,2);
                    Reservation reservation = payService.getreservationbyid(Integer.parseInt(account));
                    reservation.setStatus("y");
                    reservationService.update(reservation);
                    PayRecord payRecord =new PayRecord();
                    payRecord.setFee(new BigDecimal(params.get("total_amount")));
                    Date dNow = new Date( );
                    SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                    payRecord.setDateTime(ft.format(dNow));
                    payRecord.setWay("支付宝");
                    payRecord.setReservationId(reservation.getId());
                    payRecordService.add(payRecord);
                } else if ((params.get("out_trade_no").substring(0,1)).equals("Y")) {
                    String id = params.get("out_trade_no").substring(1, 2);
                    Reservation selectbypidanddtid = reservationService.selectbypidanddtid("n", Integer.parseInt(id));
                    selectbypidanddtid.setPayMentTypeId(1);
                    selectbypidanddtid.setStatus("y");
                    reservationService.update(selectbypidanddtid);
                    //添加支付记录
                    PayRecord payRecord =new PayRecord();
                    payRecord.setFee(new BigDecimal(params.get("total_amount")));
                    Date dNow = new Date( );
                    SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                    payRecord.setDateTime(ft.format(dNow));
                    payRecord.setWay("支付宝");
                    payRecord.setReservationId(selectbypidanddtid.getId());
                    payRecordService.add(payRecord);
                } else if ((params.get("out_trade_no").substring(0,1)).equals("M")) {
                    int out_trade_no = params.get("out_trade_no").length();
                    String no = params.get("out_trade_no").substring(1, out_trade_no-4);
                    String[] arr = no.split("");
                    List<Integer> list=new ArrayList<>();
                    for (String s : arr) {
                        list.add(Integer.parseInt(s));
                    }
                    for (Integer integer : list) {
                        payService.updateDPMstatusbyId(integer);
                    }
                } else if ((params.get("out_trade_no").substring(0,1)).equals("I")) {
                    int out_trade_no = params.get("out_trade_no").length();
                    String no = params.get("out_trade_no").substring(1, out_trade_no-4);
                    String[] arr = no.split("");
                    List<Integer> list=new ArrayList<>();
                    for (String s : arr) {
                        list.add(Integer.parseInt(s));
                    }
                    for (Integer integer : list) {
                        payService.updateDPIstatusbyId(integer);
                    }
                } else if ((params.get("out_trade_no").substring(0,1)).equals("C")) {
                    int out_trade_no = params.get("out_trade_no").length();
                    String no = params.get("out_trade_no").substring(1, out_trade_no-4);
                    Wallet wallet1 = walletService.getByPatientId(Integer.parseInt(no));
                    wallet1.setBalance((new BigDecimal(params.get("total_amount"))).add(wallet1.getBalance()));
                    walletService.updateWallet(wallet1);
                }
//                System.out.println("交易名称: " + params.get("subject"));
//                System.out.println("交易状态: " + params.get("trade_status"));
//                System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
//                System.out.println("商户订单号: " + params.get("out_trade_no"));
//                System.out.println("交易金额: " + params.get("total_amount"));
//                System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
//                System.out.println("买家付款时间: " + params.get("gmt_payment"));
//                System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
//                //修改预约状态和付款方式

            }
        }
        return "success";
    }
}
